package com.econ.powercloud.ems.util;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import lombok.SneakyThrows;
import org.joda.time.DateTime;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @Author : zqq
 * @Description : 与时间相关的工具类
 * @Date : 2019/8/28
 */
public class TimeUtil {

    public final static Long ONE_DAY_MILLIS = 86400000L;

    public TimeUtil() {
    }

    /**
     * From long to Date
     *
     * @return
     */
    public static Date getDateFromTime(long dateTime) {
        Date date = new Date();
        date.setTime(dateTime);
        return date;
    }

      /**
       * 将长时间格式时间转换为字符串 yyyy-MM-dd HH:mm:ss
       *
       * @param dateDate
       * @return
       */
      public static String dateToStrLong(Date dateDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         String dateString = formatter.format(dateDate);
         return dateString;
      }

    public static String dateTimeToStrLong(Long dateDate) {
          return dateToStrLong(getDateFromTime(dateDate));
    }

    /**
     * 得到某天的00:00:00开始时间戳
     *
     * @return
     */
    public static long getDayStartTime(Date dayTime) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dayTime);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND,0);
        return calendar.getTime().getTime();
    }

    /**
     * 得到某天的23:59:59结束时间戳
     *
     * @return
     */
    public static long getDayEndTime(Date dayTime) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dayTime);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND,999);
        return calendar.getTime().getTime();
    }

    /**
     * 获取当月的结束时间戳
     *
     * @return
     */
    public static Long getMonthEndTime(Date time) {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTime(time);
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));// 获取当前月最后一天
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTimeInMillis();
    }

    /**
     * 获取今年及前几年年份
     *
     * @param count 前几年
     * @return
     */
    public static List<String> getBeforeYear(int count) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        List<String> years = Lists.newArrayList();
        int thisYear = calendar.get(Calendar.YEAR);
        for (int i = 0; i <= count; i++) {
            years.add(Integer.toString(thisYear - i));
        }
        return years;
    }

    /**
     * 获取该月及前几个月的年月
     *
     * @param count 前几个月
     * @return
     */
    public static List<String> getBeforeMonth(int count) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        List<String> months = Lists.newArrayList();
        for (int i = 0; i <= count; i++) {
            String month = calendar.get(Calendar.YEAR) + "" + ((calendar.get(Calendar.MONTH) + 1) < 10 ? "0" : "") + (calendar.get(Calendar.MONTH) + 1);
            months.add(month);
            calendar.add(Calendar.MONTH, -1);
        }
        return months;
    }

    /**
     * 获取今天及前几天的年月日
     *
     * @param count 前几天
     * @return
     */
    public static List<String> getBeforeDay(int count) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        List<String> days = Lists.newArrayList();
        for (int i = 0; i <= count; i++) {
            String day = calendar.get(Calendar.YEAR) + "" + (calendar.get(Calendar.MONTH) + 1 < 10 ? "0" : "") + (calendar.get(Calendar.MONTH) + 1)
                    + (calendar.get(Calendar.DAY_OF_MONTH) < 10 ? "0" : "") + calendar.get(Calendar.DAY_OF_MONTH);
            days.add(day);
            calendar.add(Calendar.DAY_OF_MONTH, -1);
        }
        return days;
    }

    /**
     * 获取某个时间（年月日 如：20190829）开始结束时间
     *
     * @param time 时间
     * @return
     */
    public static Long[] getTimeTnterval(String time) {
        Long[] timeTnterval = new Long[2];
        Calendar calendar = Calendar.getInstance();
        int length = time.length();
        String startTime = null;
        String endTime = null;
        if (length == 4) {
            startTime = time + "0101 00:00:00";
            endTime = time + "1231 23:59:59";
        } else if (length == 6) {
            startTime = time + "01 00:00:00";
            calendar.set(Calendar.YEAR, Integer.parseInt(time.substring(0, 4)) - 1);
            calendar.set(Calendar.MONTH, Integer.parseInt(time.substring(4)));
            int monthDays = calendar.getActualMaximum(Calendar.DATE);
            endTime = time + monthDays + " 23:59:59";
        } else if (length == 8) {
            startTime = time + " 00:00:00";
            endTime = time + " 23:59:59";
        }
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
        ParsePosition pos = new ParsePosition(0);
        try {
            calendar.setTime(sf.parse(startTime));
            timeTnterval[0] = calendar.getTime().getTime();
            calendar.setTime(sf.parse(endTime));
            timeTnterval[1] = calendar.getTime().getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return timeTnterval;
    }

    /**
     * 获取当前月份第一天零点的时间戳
     *
     * @return
     */
    public static long getMonthStartTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return getDayStartTime(calendar.getTime());
    }

    /**
     * 获取指定时间的长时间戳
     * @param dateFormat, e.g. yyyy-MM-dd HH:mm
     * @param dateTime,   e.g. 2019-09-06 17:50
     * @return 1567763400000
     */
    public static long getLongUnixTimestamp(String dateFormat, String dateTime) {
        DateFormat df = new SimpleDateFormat(dateFormat);
        Date date = null;
        try {
            date = df.parse(dateTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.getTimeInMillis();
    }

    /**
     * 获取指定时间的短时间戳
     * @param dateFormat, e.g. yyyy-MM-dd HH:mm
     * @param dateTime,   e.g. 2019-09-06 17:50
     * @return 1567763400
     */
    public static int getShortUnixTimestamp(String dateFormat, String dateTime) {
        String currentTimeMillis = String.valueOf(TimeUtil.getLongUnixTimestamp(dateFormat, dateTime));
        return Integer.valueOf(currentTimeMillis.substring(0, currentTimeMillis.length() - 3));
    }

    /**
     * 时间戳转日期
     * @param ms
     * @return
     */
    public static Date transForDate(Integer ms){
        if(ms==null){
            ms=0;
        }
        long msl=(long)ms*1000;
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        Date temp=null;
        if(ms!=null){
            try {
                String str=sdf.format(msl);
                temp=sdf.parse(str);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return temp;
    }

    /**
     * 日期字符串转时间戳
     * @param dateStr
     * @param "yyyy-mm-dd"
     * @return
     */
    /*public static Integer transForMilliSecondByTim(String dateStr,String tim){
        SimpleDateFormat sdf=new SimpleDateFormat(tim);
        Date date =null;
        try {
            date = sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date == null ? null : (int)(date.getTime()/1000);
    }*/

    /**
     * 日期字符串转时间戳
     * @param time
     * @param "yyyy-mm-dd"
     * @return
     */
    public static long transForMilliSecondByStr(String time,String tim) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(tim);
        Date date = simpleDateFormat.parse(time);
        long ts = date.getTime();
        return ts;
    }


    /**
     * 获取整点小时时间戳
     */
    public static long getWholeTime(Date date){
        Calendar ca = Calendar.getInstance();
        ca.set(Calendar.MINUTE, 0);
        ca.set(Calendar.SECOND, 0);
        date = ca.getTime();
        return (date.getTime()/1000);
    }

    /**
     * 时间戳转日期字符串
     * @param "yyyy-mm-dd"
     * @param time
     * @return
     */
    public static String transForTimeStrByTime(long time,String tim){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(tim);
        String date = simpleDateFormat.format(new Date(time));
        return date;
    }
    /**
     * 获取 某天的开始时间
     */
    public static Long getStartOfDay(Date date){
        if (date == null) {
            date = new Date();
        }
        DateTime dateTime = new DateTime(date).secondOfDay().withMinimumValue().millisOfDay().withMinimumValue();
        return dateTime.toDate().getTime();
    }

    /**
     * 获取 某天的结束时间
     */
    public static Long getEndOfDay(Date date){
        if (date == null) {
            date = new Date();
        }
        DateTime dateTime = new DateTime(date).secondOfDay().withMaximumValue().millisOfDay().withMaximumValue();
        return dateTime.toDate().getTime();
    }

    /**
     * 获取当前累计小时数
     */
    public static Integer getDateToHour(Date date) {
        Calendar instance = Calendar.getInstance();
        instance.setTime(date);
        return instance.get(Calendar.HOUR_OF_DAY);
    }

    public static String format2String(Long time, DateTimeFormatter dateTimeFormatter) {
        Date date = new Date(time);
        Instant instant = date.toInstant();
        return instant.atZone(ZoneId.systemDefault()).toLocalDateTime().format(dateTimeFormatter);
    }

    /**
     * 获取两个时间戳之间的时间(格式：yyyyMMdd)
     */
    public static List<String> getDayDateBetweenTimestamp(Long startTime,Long endTime){
        startTime = getDayStartTime(new Date(startTime));
        endTime = getDayStartTime(new Date(endTime));
        List<String> dataList = Lists.newArrayList();
        while (startTime <= endTime){
            dataList.add(TimeUtil.format2String(startTime, DateTimeFormatter.ofPattern("yyyyMMdd")));
            startTime = startTime + ONE_DAY_MILLIS;
        }
        return dataList;
    }

    /**
     * 获取两个时间戳之间的时间(格式：yyyyMM)
     */
    @SneakyThrows
    public static List<String> getMonthDateBetweenTimestamp(Long startTime, Long endTime){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        List<String> list = new ArrayList<String>();
        Date startDate = sdf.parse(sdf.format(startTime));;
        Date endDate = sdf.parse(sdf.format(endTime));;
        //用Calendar 进行日期比较判断
        Calendar calendar = Calendar.getInstance();
        while (startDate.getTime()<=endDate.getTime()) {
            // 把日期添加到集合
            list.add(sdf.format(startDate));
            // 设置日期
            calendar.setTime(startDate);
            //把日期增加一天
            calendar.add(Calendar.MONTH, 1);
            // 获取增加后的日期
            startDate = calendar.getTime();
        }
        return list;
    }

    /**
     * 获取两个时间戳之间的时间(格式：yyyy)
     */
    public static List<String> getYearDateBetweenTimestamp(Long startTime,Long endTime){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        Integer startYear = Integer.parseInt(sdf.format(new Date(startTime)));
        Integer endYear = Integer.parseInt(sdf.format(new Date(endTime)));
        List<String> result = Lists.newArrayList();
        while (startYear <= endYear){
            result.add(startYear+"");
            startYear ++;
        }
        return result;
    }

    /**
     * 获取当前时间几年前的时间
     * @param  year:正数为之后的年份
     */
    public static Long getOtherYearWithYear(int year) {
        //得到一个Calendar的实例
        Calendar ca = Calendar.getInstance();
        //设置时间为当前时间
        ca.setTime(new Date());
        ca.add(Calendar.YEAR, year);
        return ca.getTime().getTime();
    }

    /**
     * 获取传入时间currentDay前amount天零点时间戳,amount为正则为后几天，为负则为前几天
     */
    public static Long getDayStartTime(Date currentDay,Integer amount) {
        //得到一个Calendar的实例
        Calendar ca = Calendar.getInstance();
        //设置时间为当前时间
        ca.setTime(currentDay);
        ca.add(Calendar.DAY_OF_MONTH,amount);
        return TimeUtil.getDayStartTime(ca.getTime());
    }
}
